Micron Document
🎖️GitЯра🎖️


Displaying Raw • Download

feature/settings/src/commonTest/kotlin/org/meshtastic/feature/settings/radio/RadioConfigViewModelTest.kt bf929c20f274232e0eb8ddc19b2dc82403e99e5b (bf929c20) Text, 37.15 KB

T8b949e/*
* Copyright (c) 2026 Meshtastic LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
Tff7b72package T7ee787org.meshtastic.feature.settings.radio

Tff7b72import T7ee787app.cash.turbine.test
Tff7b72import T7ee787dev.mokkery.MockMode
Tff7b72import T7ee787dev.mokkery.answering.calls
Tff7b72import T7ee787dev.mokkery.answering.returns
Tff7b72import T7ee787dev.mokkery.every
Tff7b72import T7ee787dev.mokkery.everySuspend
Tff7b72import T7ee787dev.mokkery.matcher.any
Tff7b72import T7ee787dev.mokkery.mock
Tff7b72import T7ee787dev.mokkery.verify
Tff7b72import T7ee787dev.mokkery.verify.VerifyMode.Companion.exactly
Tff7b72import T7ee787dev.mokkery.verifySuspend
Tff7b72import T7ee787kotlinx.coroutines.Dispatchers
Tff7b72import T7ee787kotlinx.coroutines.ExperimentalCoroutinesApi
Tff7b72import T7ee787kotlinx.coroutines.delay
Tff7b72import T7ee787kotlinx.coroutines.flow.MutableSharedFlow
Tff7b72import T7ee787kotlinx.coroutines.flow.MutableStateFlow
Tff7b72import T7ee787kotlinx.coroutines.test.UnconfinedTestDispatcher
Tff7b72import T7ee787kotlinx.coroutines.test.advanceTimeBy
Tff7b72import T7ee787kotlinx.coroutines.test.resetMain
Tff7b72import T7ee787kotlinx.coroutines.test.runCurrent
Tff7b72import T7ee787kotlinx.coroutines.test.runTest
Tff7b72import T7ee787kotlinx.coroutines.test.setMain
Tff7b72import T7ee787org.meshtastic.core.domain.usecase.settings.AdminActionsUseCase
Tff7b72import T7ee787org.meshtastic.core.domain.usecase.settings.ExportProfileUseCase
Tff7b72import T7ee787org.meshtastic.core.domain.usecase.settings.ExportSecurityConfigUseCase
Tff7b72import T7ee787org.meshtastic.core.domain.usecase.settings.ImportProfileUseCase
Tff7b72import T7ee787org.meshtastic.core.domain.usecase.settings.InstallProfileUseCase
Tff7b72import T7ee787org.meshtastic.core.domain.usecase.settings.ProcessRadioResponseUseCase
Tff7b72import T7ee787org.meshtastic.core.domain.usecase.settings.RadioConfigUseCase
Tff7b72import T7ee787org.meshtastic.core.domain.usecase.settings.RadioResponseResult
Tff7b72import T7ee787org.meshtastic.core.model.MqttProbeStatus
Tff7b72import T7ee787org.meshtastic.core.model.MyNodeInfo
Tff7b72import T7ee787org.meshtastic.core.model.Node
Tff7b72import T7ee787org.meshtastic.core.repository.AnalyticsPrefs
Tff7b72import T7ee787org.meshtastic.core.repository.FileService
Tff7b72import T7ee787org.meshtastic.core.repository.HomoglyphPrefs
Tff7b72import T7ee787org.meshtastic.core.repository.LocationRepository
Tff7b72import T7ee787org.meshtastic.core.repository.LocationService
Tff7b72import T7ee787org.meshtastic.core.repository.MapConsentPrefs
Tff7b72import T7ee787org.meshtastic.core.repository.MqttManager
Tff7b72import T7ee787org.meshtastic.core.repository.PacketRepository
Tff7b72import T7ee787org.meshtastic.core.repository.RadioConfigRepository
Tff7b72import T7ee787org.meshtastic.core.repository.ServiceRepository
Tff7b72import T7ee787org.meshtastic.core.repository.UiPrefs
Tff7b72import T7ee787org.meshtastic.core.testing.FakeLockdownCoordinator
Tff7b72import T7ee787org.meshtastic.core.testing.FakeNodeRepository
Tff7b72import T7ee787org.meshtastic.feature.settings.navigation.ConfigRoute
Tff7b72import T7ee787org.meshtastic.proto.ChannelSet
Tff7b72import T7ee787org.meshtastic.proto.ChannelSettings
Tff7b72import T7ee787org.meshtastic.proto.Config
Tff7b72import T7ee787org.meshtastic.proto.Data
Tff7b72import T7ee787org.meshtastic.proto.DeviceMetadata
Tff7b72import T7ee787org.meshtastic.proto.DeviceProfile
Tff7b72import T7ee787org.meshtastic.proto.HamParameters
Tff7b72import T7ee787org.meshtastic.proto.LoRaPresetGroup
Tff7b72import T7ee787org.meshtastic.proto.LoRaRegionPresetMap
Tff7b72import T7ee787org.meshtastic.proto.LocalConfig
Tff7b72import T7ee787org.meshtastic.proto.LocalModuleConfig
Tff7b72import T7ee787org.meshtastic.proto.MeshPacket
Tff7b72import T7ee787org.meshtastic.proto.User
Tff7b72import T7ee787kotlin.test.AfterTest
Tff7b72import T7ee787kotlin.test.BeforeTest
Tff7b72import T7ee787kotlin.test.Test
Tff7b72import T7ee787kotlin.test.assertEquals
Tff7b72import T7ee787kotlin.test.assertFalse
Tff7b72import T7ee787kotlin.test.assertTrue

Tf0883e@OptInTb4b4b4(Te6edf3ExperimentalCoroutinesApiTff7b72::Te6edf3classTb4b4b4)
Tff7b72class T56d364RadioConfigViewModelTest Tb4b4b4{

Tff7b72private Tff7b72val Te6edf3testDispatcher Tff7b72= Te6edf3UnconfinedTestDispatcherTb4b4b4(Tb4b4b4)

Tff7b72private Tff7b72val Te6edf3radioConfigRepositoryTb4b4b4: Te6edf3RadioConfigRepository Tff7b72= Te6edf3mockTb4b4b4(Te6edf3MockModeTb4b4b4.Te6edf3autofillTb4b4b4)
Tff7b72private Tff7b72val Te6edf3packetRepositoryTb4b4b4: Te6edf3PacketRepository Tff7b72= Te6edf3mockTb4b4b4(Te6edf3MockModeTb4b4b4.Te6edf3autofillTb4b4b4)
Tff7b72private Tff7b72val Te6edf3serviceRepositoryTb4b4b4: Te6edf3ServiceRepository Tff7b72= Te6edf3mockTb4b4b4(Te6edf3MockModeTb4b4b4.Te6edf3autofillTb4b4b4)
Tff7b72private Tff7b72val Te6edf3nodeRepository Tff7b72= Te6edf3FakeNodeRepositoryTb4b4b4(Tb4b4b4)
Tff7b72private Tff7b72val Te6edf3locationRepositoryTb4b4b4: Te6edf3LocationRepository Tff7b72= Te6edf3mockTb4b4b4(Te6edf3MockModeTb4b4b4.Te6edf3autofillTb4b4b4)
Tff7b72private Tff7b72val Te6edf3mapConsentPrefsTb4b4b4: Te6edf3MapConsentPrefs Tff7b72= Te6edf3mockTb4b4b4(Te6edf3MockModeTb4b4b4.Te6edf3autofillTb4b4b4)
Tff7b72private Tff7b72val Te6edf3analyticsPrefsTb4b4b4: Te6edf3AnalyticsPrefs Tff7b72= Te6edf3mockTb4b4b4(Te6edf3MockModeTb4b4b4.Te6edf3autofillTb4b4b4)
Tff7b72private Tff7b72val Te6edf3homoglyphEncodingPrefsTb4b4b4: Te6edf3HomoglyphPrefs Tff7b72= Te6edf3mockTb4b4b4(Te6edf3MockModeTb4b4b4.Te6edf3autofillTb4b4b4)

Tff7b72private Tff7b72val Te6edf3importProfileUseCaseTb4b4b4: Te6edf3ImportProfileUseCase Tff7b72= Te6edf3mockTb4b4b4(Te6edf3MockModeTb4b4b4.Te6edf3autofillTb4b4b4)
Tff7b72private Tff7b72val Te6edf3exportProfileUseCaseTb4b4b4: Te6edf3ExportProfileUseCase Tff7b72= Te6edf3mockTb4b4b4(Te6edf3MockModeTb4b4b4.Te6edf3autofillTb4b4b4)
Tff7b72private Tff7b72val Te6edf3exportSecurityConfigUseCaseTb4b4b4: Te6edf3ExportSecurityConfigUseCase Tff7b72= Te6edf3mockTb4b4b4(Te6edf3MockModeTb4b4b4.Te6edf3autofillTb4b4b4)
Tff7b72private Tff7b72val Te6edf3installProfileUseCaseTb4b4b4: Te6edf3InstallProfileUseCase Tff7b72= Te6edf3mockTb4b4b4(Te6edf3MockModeTb4b4b4.Te6edf3autofillTb4b4b4)
Tff7b72private Tff7b72val Te6edf3radioConfigUseCaseTb4b4b4: Te6edf3RadioConfigUseCase Tff7b72= Te6edf3mockTb4b4b4(Te6edf3MockModeTb4b4b4.Te6edf3autofillTb4b4b4)
Tff7b72private Tff7b72val Te6edf3adminActionsUseCaseTb4b4b4: Te6edf3AdminActionsUseCase Tff7b72= Te6edf3mockTb4b4b4(Te6edf3MockModeTb4b4b4.Te6edf3autofillTb4b4b4)
Tff7b72private Tff7b72val Te6edf3processRadioResponseUseCaseTb4b4b4: Te6edf3ProcessRadioResponseUseCase Tff7b72= Te6edf3mockTb4b4b4(Te6edf3MockModeTb4b4b4.Te6edf3autofillTb4b4b4)
Tff7b72private Tff7b72val Te6edf3locationServiceTb4b4b4: Te6edf3LocationService Tff7b72= Te6edf3mockTb4b4b4(Te6edf3MockModeTb4b4b4.Te6edf3autofillTb4b4b4)
Tff7b72private Tff7b72val Te6edf3fileServiceTb4b4b4: Te6edf3FileService Tff7b72= Te6edf3mockTb4b4b4(Te6edf3MockModeTb4b4b4.Te6edf3autofillTb4b4b4)
Tff7b72private Tff7b72val Te6edf3mqttManagerTb4b4b4: Te6edf3MqttManager Tff7b72= Te6edf3mockTb4b4b4(Te6edf3MockModeTb4b4b4.Te6edf3autofillTb4b4b4)
Tff7b72private Tff7b72val Te6edf3uiPrefsTb4b4b4: Te6edf3UiPrefs Tff7b72= Te6edf3mockTb4b4b4(Te6edf3MockModeTb4b4b4.Te6edf3autofillTb4b4b4)

Tff7b72private Tff7b72lateinit Tff7b72var Te6edf3viewModelTb4b4b4: Te6edf3RadioConfigViewModel

Tf0883e@BeforeTest
Tff7b72fun Td2a8ffsetUpTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3DispatchersTb4b4b4.Te6edf3setMainTb4b4b4(Te6edf3testDispatcherTb4b4b4)

Te6edf3every Tb4b4b4{ Te6edf3radioConfigRepositoryTb4b4b4.Te6edf3deviceProfileFlow Tb4b4b4} Te6edf3returns Te6edf3MutableStateFlowTb4b4b4(Te6edf3DeviceProfileTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3radioConfigRepositoryTb4b4b4.Te6edf3localConfigFlow Tb4b4b4} Te6edf3returns Te6edf3MutableStateFlowTb4b4b4(Te6edf3LocalConfigTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3radioConfigRepositoryTb4b4b4.Te6edf3channelSetFlow Tb4b4b4} Te6edf3returns Te6edf3MutableStateFlowTb4b4b4(Te6edf3ChannelSetTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3radioConfigRepositoryTb4b4b4.Te6edf3moduleConfigFlow Tb4b4b4} Te6edf3returns Te6edf3MutableStateFlowTb4b4b4(Te6edf3LocalModuleConfigTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3radioConfigRepositoryTb4b4b4.Te6edf3deviceUIConfigFlow Tb4b4b4} Te6edf3returns Te6edf3MutableStateFlowTb4b4b4(Tff7b72nullTb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3radioConfigRepositoryTb4b4b4.Te6edf3fileManifestFlow Tb4b4b4} Te6edf3returns Te6edf3MutableStateFlowTb4b4b4(Te6edf3emptyListTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3radioConfigRepositoryTb4b4b4.Te6edf3loraRegionPresetMapFlow Tb4b4b4} Te6edf3returns Te6edf3MutableStateFlowTb4b4b4(Tff7b72nullTb4b4b4)

Te6edf3every Tb4b4b4{ Te6edf3analyticsPrefsTb4b4b4.Te6edf3analyticsAllowed Tb4b4b4} Te6edf3returns Te6edf3MutableStateFlowTb4b4b4(Tff7b72falseTb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3homoglyphEncodingPrefsTb4b4b4.Te6edf3homoglyphEncodingEnabled Tb4b4b4} Te6edf3returns Te6edf3MutableStateFlowTb4b4b4(Tff7b72falseTb4b4b4)

Te6edf3every Tb4b4b4{ Te6edf3serviceRepositoryTb4b4b4.Te6edf3meshPacketFlow Tb4b4b4} Te6edf3returns Te6edf3MutableSharedFlowTb4b4b4(Tb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3serviceRepositoryTb4b4b4.Te6edf3connectionState Tb4b4b4} Te6edf3returns
Te6edf3MutableStateFlowTb4b4b4(Te6edf3orgTb4b4b4.Te6edf3meshtasticTb4b4b4.Te6edf3coreTb4b4b4.Te6edf3modelTb4b4b4.Te6edf3ConnectionStateTb4b4b4.Te6edf3ConnectedTb4b4b4)

Te6edf3every Tb4b4b4{ Te6edf3mqttManagerTb4b4b4.Te6edf3mqttConnectionState Tb4b4b4} Te6edf3returns
Te6edf3MutableStateFlowTb4b4b4(Te6edf3orgTb4b4b4.Te6edf3meshtasticTb4b4b4.Te6edf3coreTb4b4b4.Te6edf3modelTb4b4b4.Te6edf3MqttConnectionStateTb4b4b4.Te6edf3InactiveTb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3mqttManagerTb4b4b4.Te6edf3proxyActive Tb4b4b4} Te6edf3returns Te6edf3MutableStateFlowTb4b4b4(Tff7b72falseTb4b4b4)

Te6edf3every Tb4b4b4{ Te6edf3uiPrefsTb4b4b4.Te6edf3showQuickChat Tb4b4b4} Te6edf3returns Te6edf3MutableStateFlowTb4b4b4(Tff7b72falseTb4b4b4)

Te6edf3viewModel Tff7b72= Te6edf3createViewModelTb4b4b4(Tb4b4b4)
Tb4b4b4}

Tf0883e@AfterTest
Tff7b72fun Td2a8fftearDownTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3DispatchersTb4b4b4.Te6edf3resetMainTb4b4b4(Tb4b4b4)
Tb4b4b4}

Tff7b72private Tff7b72fun Td2a8ffcreateViewModelTb4b4b4(Te6edf3destNumTb4b4b4: Tffa657Int? Tff7b72= Tff7b72nullTb4b4b4) Tff7b72= Te6edf3RadioConfigViewModelTb4b4b4(
Te6edf3destNum Tff7b72= Te6edf3destNumTb4b4b4,
Te6edf3radioConfigRepository Tff7b72= Te6edf3radioConfigRepositoryTb4b4b4,
Te6edf3packetRepository Tff7b72= Te6edf3packetRepositoryTb4b4b4,
Te6edf3serviceRepository Tff7b72= Te6edf3serviceRepositoryTb4b4b4,
Te6edf3nodeRepository Tff7b72= Te6edf3nodeRepositoryTb4b4b4,
Te6edf3locationRepository Tff7b72= Te6edf3locationRepositoryTb4b4b4,
Te6edf3mapConsentPrefs Tff7b72= Te6edf3mapConsentPrefsTb4b4b4,
Te6edf3analyticsPrefs Tff7b72= Te6edf3analyticsPrefsTb4b4b4,
Te6edf3homoglyphEncodingPrefs Tff7b72= Te6edf3homoglyphEncodingPrefsTb4b4b4,
Te6edf3importProfileUseCase Tff7b72= Te6edf3importProfileUseCaseTb4b4b4,
Te6edf3exportProfileUseCase Tff7b72= Te6edf3exportProfileUseCaseTb4b4b4,
Te6edf3exportSecurityConfigUseCase Tff7b72= Te6edf3exportSecurityConfigUseCaseTb4b4b4,
Te6edf3installProfileUseCase Tff7b72= Te6edf3installProfileUseCaseTb4b4b4,
Te6edf3radioConfigUseCase Tff7b72= Te6edf3radioConfigUseCaseTb4b4b4,
Te6edf3adminActionsUseCase Tff7b72= Te6edf3adminActionsUseCaseTb4b4b4,
Te6edf3processRadioResponseUseCase Tff7b72= Te6edf3processRadioResponseUseCaseTb4b4b4,
Te6edf3locationService Tff7b72= Te6edf3locationServiceTb4b4b4,
Te6edf3fileService Tff7b72= Te6edf3fileServiceTb4b4b4,
Te6edf3mqttManager Tff7b72= Te6edf3mqttManagerTb4b4b4,
Te6edf3lockdownCoordinator Tff7b72= Te6edf3FakeLockdownCoordinatorTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4)

Tf0883e@Test
Tff7b72fun Td2a8ff`setConfig calls useCase`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3node Tff7b72= Te6edf3NodeTb4b4b4(Te6edf3num Tff7b72= T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!123Ta5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3nodeRepositoryTb4b4b4.Te6edf3setNodesTb4b4b4(Te6edf3listOfTb4b4b4(Te6edf3nodeTb4b4b4)Tb4b4b4)
Te6edf3viewModel Tff7b72= Te6edf3createViewModelTb4b4b4(Tb4b4b4)

Tff7b72val Te6edf3config Tff7b72= Te6edf3ConfigTb4b4b4(Te6edf3device Tff7b72= Te6edf3ConfigTb4b4b4.Te6edf3DeviceConfigTb4b4b4(Te6edf3role Tff7b72= Te6edf3ConfigTb4b4b4.Te6edf3DeviceConfigTb4b4b4.Te6edf3RoleTb4b4b4.Te6edf3ROUTERTb4b4b4)Tb4b4b4)
Te6edf3everySuspend Tb4b4b4{ Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3setConfigTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3returns T79c0ff4T79c0ff2

Te6edf3viewModelTb4b4b4.Te6edf3setConfigTb4b4b4(Te6edf3configTb4b4b4)

Te6edf3viewModelTb4b4b4.Te6edf3radioConfigStateTb4b4b4.Te6edf3test Tb4b4b4{
Tff7b72val Te6edf3state Tff7b72= Te6edf3awaitItemTb4b4b4(Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(Te6edf3ConfigTb4b4b4.Te6edf3DeviceConfigTb4b4b4.Te6edf3RoleTb4b4b4.Te6edf3ROUTERTb4b4b4, Te6edf3stateTb4b4b4.Te6edf3radioConfigTb4b4b4.Te6edf3deviceTff7b72?.Te6edf3roleTb4b4b4)
Te6edf3cancelAndIgnoreRemainingEventsTb4b4b4(Tb4b4b4)
Tb4b4b4}

Te6edf3verifySuspend Tb4b4b4{ Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3setConfigTb4b4b4(T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3configTb4b4b4) Tb4b4b4}
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`toggleAnalyticsAllowed calls prefs`Tb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3every Tb4b4b4{ Te6edf3analyticsPrefsTb4b4b4.Te6edf3analyticsAllowed Tb4b4b4} Te6edf3returns Te6edf3MutableStateFlowTb4b4b4(Tff7b72trueTb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3analyticsPrefsTb4b4b4.Te6edf3setAnalyticsAllowedTb4b4b4(Tff7b72falseTb4b4b4) Tb4b4b4} Te6edf3returns Tffa657Unit

Te6edf3viewModelTb4b4b4.Te6edf3toggleAnalyticsAllowedTb4b4b4(Tb4b4b4)

Te6edf3verify Tb4b4b4{ Te6edf3analyticsPrefsTb4b4b4.Te6edf3setAnalyticsAllowedTb4b4b4(Tff7b72falseTb4b4b4) Tb4b4b4}
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`toggleHomoglyphCharactersEncodingEnabled calls prefs`Tb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3every Tb4b4b4{ Te6edf3homoglyphEncodingPrefsTb4b4b4.Te6edf3homoglyphEncodingEnabled Tb4b4b4} Te6edf3returns Te6edf3MutableStateFlowTb4b4b4(Tff7b72trueTb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3homoglyphEncodingPrefsTb4b4b4.Te6edf3setHomoglyphEncodingEnabledTb4b4b4(Tff7b72falseTb4b4b4) Tb4b4b4} Te6edf3returns Tffa657Unit

Te6edf3viewModelTb4b4b4.Te6edf3toggleHomoglyphCharactersEncodingEnabledTb4b4b4(Tb4b4b4)

Te6edf3verify Tb4b4b4{ Te6edf3homoglyphEncodingPrefsTb4b4b4.Te6edf3setHomoglyphEncodingEnabledTb4b4b4(Tff7b72falseTb4b4b4) Tb4b4b4}
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`processPacketResponse updates state on metadata result`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3node Tff7b72= Te6edf3NodeTb4b4b4(Te6edf3num Tff7b72= T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!123Ta5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3nodeRepositoryTb4b4b4.Te6edf3setNodesTb4b4b4(Te6edf3listOfTb4b4b4(Te6edf3nodeTb4b4b4)Tb4b4b4)

Tff7b72val Te6edf3packet Tff7b72= Te6edf3MeshPacketTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3metadata Tff7b72= Te6edf3DeviceMetadataTb4b4b4(Te6edf3firmware_version Tff7b72= Ta5d6ff"Ta5d6ff3.0.0Ta5d6ff"Tb4b4b4)
Tff7b72val Te6edf3packetFlow Tff7b72= Te6edf3MutableSharedFlowTff7b72<Te6edf3MeshPacketTff7b72>Tb4b4b4(Tb4b4b4)

Te6edf3every Tb4b4b4{ Te6edf3serviceRepositoryTb4b4b4.Te6edf3meshPacketFlow Tb4b4b4} Te6edf3returns Te6edf3packetFlow
Te6edf3every Tb4b4b4{ Te6edf3processRadioResponseUseCaseTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3returns Te6edf3RadioResponseResultTb4b4b4.Te6edf3MetadataTb4b4b4(Te6edf3metadataTb4b4b4)

Te6edf3viewModel Tff7b72= Te6edf3createViewModelTb4b4b4(Tb4b4b4)

Te6edf3packetFlowTb4b4b4.Te6edf3emitTb4b4b4(Te6edf3packetTb4b4b4)

Te6edf3viewModelTb4b4b4.Te6edf3radioConfigStateTb4b4b4.Te6edf3test Tb4b4b4{
Tff7b72val Te6edf3state Tff7b72= Te6edf3awaitItemTb4b4b4(Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(Ta5d6ff"Ta5d6ff3.0.0Ta5d6ff"Tb4b4b4, Te6edf3stateTb4b4b4.Te6edf3metadataTff7b72?.Te6edf3firmware_versionTb4b4b4)
Te6edf3cancelAndIgnoreRemainingEventsTb4b4b4(Tb4b4b4)
Tb4b4b4}
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`probeMqttConnection updates status for success`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Te6edf3everySuspend Tb4b4b4{ Te6edf3mqttManagerTb4b4b4.Te6edf3probeTb4b4b4(Ta5d6ff"Ta5d6ffmqtt.example.comTa5d6ff"Tb4b4b4, Tff7b72trueTb4b4b4, Ta5d6ff"Ta5d6ffuserTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffpassTa5d6ff"Tb4b4b4) Tb4b4b4}
Tb4b4b4.Te6edf3calls Tb4b4b4{
Te6edf3delayTb4b4b4(T79c0ff1Tb4b4b4)
Te6edf3MqttProbeStatusTb4b4b4.Te6edf3SuccessTb4b4b4(Te6edf3serverInfo Tff7b72= Ta5d6ff"Ta5d6ffclient=testTa5d6ff"Tb4b4b4)
Tb4b4b4}

Te6edf3viewModelTb4b4b4.Te6edf3probeMqttConnectionTb4b4b4(Ta5d6ff"Ta5d6ffmqtt.example.comTa5d6ff"Tb4b4b4, Tff7b72trueTb4b4b4, Ta5d6ff"Ta5d6ffuserTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffpassTa5d6ff"Tb4b4b4)

Te6edf3assertEqualsTb4b4b4(Te6edf3MqttProbeStatusTb4b4b4.Te6edf3ProbingTb4b4b4, Te6edf3viewModelTb4b4b4.Te6edf3mqttProbeStatusTb4b4b4.Te6edf3valueTb4b4b4)

Te6edf3advanceTimeByTb4b4b4(T79c0ff1Tb4b4b4)
Te6edf3runCurrentTb4b4b4(Tb4b4b4)

Te6edf3assertEqualsTb4b4b4(Te6edf3MqttProbeStatusTb4b4b4.Te6edf3SuccessTb4b4b4(Te6edf3serverInfo Tff7b72= Ta5d6ff"Ta5d6ffclient=testTa5d6ff"Tb4b4b4)Tb4b4b4, Te6edf3viewModelTb4b4b4.Te6edf3mqttProbeStatusTb4b4b4.Te6edf3valueTb4b4b4)
Te6edf3verifySuspend Tb4b4b4{ Te6edf3mqttManagerTb4b4b4.Te6edf3probeTb4b4b4(Ta5d6ff"Ta5d6ffmqtt.example.comTa5d6ff"Tb4b4b4, Tff7b72trueTb4b4b4, Ta5d6ff"Ta5d6ffuserTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffpassTa5d6ff"Tb4b4b4) Tb4b4b4}
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`probeMqttConnection updates status for timeout`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Te6edf3everySuspend Tb4b4b4{ Te6edf3mqttManagerTb4b4b4.Te6edf3probeTb4b4b4(Ta5d6ff"Ta5d6ffmqtt.example.comTa5d6ff"Tb4b4b4, Tff7b72falseTb4b4b4, Tff7b72nullTb4b4b4, Tff7b72nullTb4b4b4) Tb4b4b4} Te6edf3returns Te6edf3MqttProbeStatusTb4b4b4.Te6edf3TimeoutTb4b4b4(T79c0ff5Te6edf3_000Tb4b4b4)

Te6edf3viewModelTb4b4b4.Te6edf3probeMqttConnectionTb4b4b4(Ta5d6ff"Ta5d6ffmqtt.example.comTa5d6ff"Tb4b4b4, Tff7b72falseTb4b4b4, Tff7b72nullTb4b4b4, Tff7b72nullTb4b4b4)
Te6edf3runCurrentTb4b4b4(Tb4b4b4)

Te6edf3assertEqualsTb4b4b4(Te6edf3MqttProbeStatusTb4b4b4.Te6edf3TimeoutTb4b4b4(T79c0ff5Te6edf3_000Tb4b4b4)Tb4b4b4, Te6edf3viewModelTb4b4b4.Te6edf3mqttProbeStatusTb4b4b4.Te6edf3valueTb4b4b4)
Te6edf3verifySuspend Tb4b4b4{ Te6edf3mqttManagerTb4b4b4.Te6edf3probeTb4b4b4(Ta5d6ff"Ta5d6ffmqtt.example.comTa5d6ff"Tb4b4b4, Tff7b72falseTb4b4b4, Tff7b72nullTb4b4b4, Tff7b72nullTb4b4b4) Tb4b4b4}
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`probeMqttConnection converts thrown exception to other status`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Te6edf3everySuspend Tb4b4b4{ Te6edf3mqttManagerTb4b4b4.Te6edf3probeTb4b4b4(Ta5d6ff"Ta5d6ffmqtt.example.comTa5d6ff"Tb4b4b4, Tff7b72trueTb4b4b4, Tff7b72nullTb4b4b4, Tff7b72nullTb4b4b4) Tb4b4b4}
Tb4b4b4.Te6edf3calls Tb4b4b4{ Tff7b72throw Te6edf3IllegalStateExceptionTb4b4b4(Ta5d6ff"Ta5d6ffboomTa5d6ff"Tb4b4b4) Tb4b4b4}

Te6edf3viewModelTb4b4b4.Te6edf3probeMqttConnectionTb4b4b4(Ta5d6ff"Ta5d6ffmqtt.example.comTa5d6ff"Tb4b4b4, Tff7b72trueTb4b4b4, Tff7b72nullTb4b4b4, Tff7b72nullTb4b4b4)
Te6edf3runCurrentTb4b4b4(Tb4b4b4)

Te6edf3assertEqualsTb4b4b4(Te6edf3MqttProbeStatusTb4b4b4.Te6edf3OtherTb4b4b4(Te6edf3message Tff7b72= Ta5d6ff"Ta5d6ffboomTa5d6ff"Tb4b4b4)Tb4b4b4, Te6edf3viewModelTb4b4b4.Te6edf3mqttProbeStatusTb4b4b4.Te6edf3valueTb4b4b4)
Te6edf3verifySuspend Tb4b4b4{ Te6edf3mqttManagerTb4b4b4.Te6edf3probeTb4b4b4(Ta5d6ff"Ta5d6ffmqtt.example.comTa5d6ff"Tb4b4b4, Tff7b72trueTb4b4b4, Tff7b72nullTb4b4b4, Tff7b72nullTb4b4b4) Tb4b4b4}
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`setMqttProxyActive false stops the proxy without touching device config`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Te6edf3every Tb4b4b4{ Te6edf3mqttManagerTb4b4b4.Te6edf3stopTb4b4b4(Tb4b4b4) Tb4b4b4} Te6edf3returns Tffa657Unit

Te6edf3viewModelTb4b4b4.Te6edf3setMqttProxyActiveTb4b4b4(Tff7b72falseTb4b4b4)

Te6edf3verify Tb4b4b4{ Te6edf3mqttManagerTb4b4b4.Te6edf3stopTb4b4b4(Tb4b4b4) Tb4b4b4}
T8b949e// Phone-local cut must not issue any device config read/write.
Te6edf3verifySuspendTb4b4b4(Te6edf3exactlyTb4b4b4(T79c0ff0Tb4b4b4)Tb4b4b4) Tb4b4b4{ Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3setModuleConfigTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`setMqttProxyActive true restarts proxy using current device module config`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Te6edf3every Tb4b4b4{ Te6edf3radioConfigRepositoryTb4b4b4.Te6edf3moduleConfigFlow Tb4b4b4} Te6edf3returns
Te6edf3MutableStateFlowTb4b4b4(
Te6edf3LocalModuleConfigTb4b4b4(
Te6edf3mqtt Tff7b72= Te6edf3orgTb4b4b4.Te6edf3meshtasticTb4b4b4.Te6edf3protoTb4b4b4.Te6edf3ModuleConfigTb4b4b4.Te6edf3MQTTConfigTb4b4b4(Te6edf3enabled Tff7b72= Tff7b72trueTb4b4b4, Te6edf3proxy_to_client_enabled Tff7b72= Tff7b72trueTb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3mqttManagerTb4b4b4.Te6edf3startProxyTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3returns Tffa657Unit
Te6edf3viewModel Tff7b72= Te6edf3createViewModelTb4b4b4(Tb4b4b4)
Te6edf3runCurrentTb4b4b4(Tb4b4b4)

Te6edf3viewModelTb4b4b4.Te6edf3setMqttProxyActiveTb4b4b4(Tff7b72trueTb4b4b4)

Te6edf3verify Tb4b4b4{ Te6edf3mqttManagerTb4b4b4.Te6edf3startProxyTb4b4b4(Tff7b72trueTb4b4b4, Tff7b72trueTb4b4b4) Tb4b4b4}
Te6edf3verifySuspendTb4b4b4(Te6edf3exactlyTb4b4b4(T79c0ff0Tb4b4b4)Tb4b4b4) Tb4b4b4{ Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3setModuleConfigTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`setMqttProxyActive true is a no-op start when device MQTT is disabled`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Te6edf3every Tb4b4b4{ Te6edf3radioConfigRepositoryTb4b4b4.Te6edf3moduleConfigFlow Tb4b4b4} Te6edf3returns Te6edf3MutableStateFlowTb4b4b4(Te6edf3LocalModuleConfigTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3mqttManagerTb4b4b4.Te6edf3startProxyTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3returns Tffa657Unit
Te6edf3viewModel Tff7b72= Te6edf3createViewModelTb4b4b4(Tb4b4b4)
Te6edf3runCurrentTb4b4b4(Tb4b4b4)

Te6edf3viewModelTb4b4b4.Te6edf3setMqttProxyActiveTb4b4b4(Tff7b72trueTb4b4b4)

T8b949e// The manager is still asked to start, but with both flags false it does nothing (its own guard).
Te6edf3verify Tb4b4b4{ Te6edf3mqttManagerTb4b4b4.Te6edf3startProxyTb4b4b4(Tff7b72falseTb4b4b4, Tff7b72falseTb4b4b4) Tb4b4b4}
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`clearMqttProbeStatus resets probe state`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Te6edf3everySuspend Tb4b4b4{ Te6edf3mqttManagerTb4b4b4.Te6edf3probeTb4b4b4(Ta5d6ff"Ta5d6ffmqtt.example.comTa5d6ff"Tb4b4b4, Tff7b72falseTb4b4b4, Tff7b72nullTb4b4b4, Tff7b72nullTb4b4b4) Tb4b4b4}
Tb4b4b4.Te6edf3calls Tb4b4b4{
Te6edf3delayTb4b4b4(T79c0ff1Tb4b4b4)
Te6edf3MqttProbeStatusTb4b4b4.Te6edf3SuccessTb4b4b4(Te6edf3serverInfo Tff7b72= Ta5d6ff"Ta5d6ffclient=testTa5d6ff"Tb4b4b4)
Tb4b4b4}

Te6edf3viewModelTb4b4b4.Te6edf3probeMqttConnectionTb4b4b4(Ta5d6ff"Ta5d6ffmqtt.example.comTa5d6ff"Tb4b4b4, Tff7b72falseTb4b4b4, Tff7b72nullTb4b4b4, Tff7b72nullTb4b4b4)
Te6edf3assertEqualsTb4b4b4(Te6edf3MqttProbeStatusTb4b4b4.Te6edf3ProbingTb4b4b4, Te6edf3viewModelTb4b4b4.Te6edf3mqttProbeStatusTb4b4b4.Te6edf3valueTb4b4b4)

Te6edf3viewModelTb4b4b4.Te6edf3clearMqttProbeStatusTb4b4b4(Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(Tff7b72nullTb4b4b4, Te6edf3viewModelTb4b4b4.Te6edf3mqttProbeStatusTb4b4b4.Te6edf3valueTb4b4b4)

Te6edf3advanceTimeByTb4b4b4(T79c0ff1Tb4b4b4)
Te6edf3runCurrentTb4b4b4(Tb4b4b4)

Te6edf3assertEqualsTb4b4b4(Tff7b72nullTb4b4b4, Te6edf3viewModelTb4b4b4.Te6edf3mqttProbeStatusTb4b4b4.Te6edf3valueTb4b4b4)
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`updateChannels calls useCase for each changed channel`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3node Tff7b72= Te6edf3NodeTb4b4b4(Te6edf3num Tff7b72= T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!123Ta5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3nodeRepositoryTb4b4b4.Te6edf3setNodesTb4b4b4(Te6edf3listOfTb4b4b4(Te6edf3nodeTb4b4b4)Tb4b4b4)
Te6edf3viewModel Tff7b72= Te6edf3createViewModelTb4b4b4(Tb4b4b4)

Tff7b72val Te6edf3old Tff7b72= Te6edf3listOfTb4b4b4(Te6edf3ChannelSettingsTb4b4b4(Te6edf3name Tff7b72= Ta5d6ff"Ta5d6ffOldTa5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72val Te6edf3new Tff7b72= Te6edf3listOfTb4b4b4(Te6edf3ChannelSettingsTb4b4b4(Te6edf3name Tff7b72= Ta5d6ff"Ta5d6ffNewTa5d6ff"Tb4b4b4)Tb4b4b4)

Te6edf3everySuspend Tb4b4b4{ Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3setRemoteChannelTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3returns T79c0ff4T79c0ff2

Te6edf3viewModelTb4b4b4.Te6edf3updateChannelsTb4b4b4(Te6edf3newTb4b4b4, Te6edf3oldTb4b4b4)

Te6edf3verifySuspend Tb4b4b4{ Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3setRemoteChannelTb4b4b4(T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Te6edf3assertEqualsTb4b4b4(Te6edf3newTb4b4b4, Te6edf3viewModelTb4b4b4.Te6edf3radioConfigStateTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3channelListTb4b4b4)
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`setResponseStateLoading for REBOOT calls useCase after config response`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3node Tff7b72= Te6edf3NodeTb4b4b4(Te6edf3num Tff7b72= T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!123Ta5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3nodeRepositoryTb4b4b4.Te6edf3setNodesTb4b4b4(Te6edf3listOfTb4b4b4(Te6edf3nodeTb4b4b4)Tb4b4b4)

Tff7b72val Te6edf3packetFlow Tff7b72= Te6edf3MutableSharedFlowTff7b72<Te6edf3MeshPacketTff7b72>Tb4b4b4(Tb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3serviceRepositoryTb4b4b4.Te6edf3meshPacketFlow Tb4b4b4} Te6edf3returns Te6edf3packetFlow
T8b949e// AdminRoute first sends a session key config request; the admin action fires
T8b949e// only after the actual ConfigResponse (not a routing ACK / Success).
Te6edf3every Tb4b4b4{ Te6edf3processRadioResponseUseCaseTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3returns Te6edf3RadioResponseResultTb4b4b4.Te6edf3ConfigResponseTb4b4b4(Te6edf3ConfigTb4b4b4(Tb4b4b4)Tb4b4b4)

Te6edf3viewModel Tff7b72= Te6edf3createViewModelTb4b4b4(Tb4b4b4)

Te6edf3everySuspend Tb4b4b4{ Te6edf3adminActionsUseCaseTb4b4b4.Te6edf3rebootTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3returns T79c0ff4T79c0ff2

Te6edf3viewModelTb4b4b4.Te6edf3setResponseStateLoadingTb4b4b4(Te6edf3AdminRouteTb4b4b4.Te6edf3REBOOTTb4b4b4)

T8b949e// Emit a config response packet to trigger processPacketResponse -> sendAdminRequest
Te6edf3packetFlowTb4b4b4.Te6edf3emitTb4b4b4(Te6edf3MeshPacketTb4b4b4(Tb4b4b4)Tb4b4b4)

Te6edf3verifySuspend Tb4b4b4{ Te6edf3adminActionsUseCaseTb4b4b4.Te6edf3rebootTb4b4b4(T79c0ff1T79c0ff2T79c0ff3Tb4b4b4) Tb4b4b4}
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`setResponseStateLoading for FACTORY_RESET calls useCase after config response`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3node Tff7b72= Te6edf3NodeTb4b4b4(Te6edf3num Tff7b72= T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!123Ta5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3nodeRepositoryTb4b4b4.Te6edf3setNodesTb4b4b4(Te6edf3listOfTb4b4b4(Te6edf3nodeTb4b4b4)Tb4b4b4)

Tff7b72val Te6edf3packetFlow Tff7b72= Te6edf3MutableSharedFlowTff7b72<Te6edf3MeshPacketTff7b72>Tb4b4b4(Tb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3serviceRepositoryTb4b4b4.Te6edf3meshPacketFlow Tb4b4b4} Te6edf3returns Te6edf3packetFlow
T8b949e// AdminRoute first sends a session key config request; the admin action fires
T8b949e// only after the actual ConfigResponse (not a routing ACK / Success).
Te6edf3every Tb4b4b4{ Te6edf3processRadioResponseUseCaseTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3returns Te6edf3RadioResponseResultTb4b4b4.Te6edf3ConfigResponseTb4b4b4(Te6edf3ConfigTb4b4b4(Tb4b4b4)Tb4b4b4)

Te6edf3viewModel Tff7b72= Te6edf3createViewModelTb4b4b4(Tb4b4b4)

Te6edf3everySuspend Tb4b4b4{ Te6edf3adminActionsUseCaseTb4b4b4.Te6edf3factoryResetTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3returns T79c0ff4T79c0ff2

Te6edf3viewModelTb4b4b4.Te6edf3setResponseStateLoadingTb4b4b4(Te6edf3AdminRouteTb4b4b4.Te6edf3FACTORY_RESETTb4b4b4)

T8b949e// Emit a config response packet to trigger processPacketResponse -> sendAdminRequest
Te6edf3packetFlowTb4b4b4.Te6edf3emitTb4b4b4(Te6edf3MeshPacketTb4b4b4(Tb4b4b4)Tb4b4b4)

Te6edf3verifySuspend Tb4b4b4{ Te6edf3adminActionsUseCaseTb4b4b4.Te6edf3factoryResetTb4b4b4(T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`setPreserveFavorites updates state`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Te6edf3viewModelTb4b4b4.Te6edf3radioConfigStateTb4b4b4.Te6edf3test Tb4b4b4{
Te6edf3assertEqualsTb4b4b4(Tff7b72falseTb4b4b4, Te6edf3awaitItemTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3nodeDbResetPreserveFavoritesTb4b4b4)
Te6edf3viewModelTb4b4b4.Te6edf3setPreserveFavoritesTb4b4b4(Tff7b72trueTb4b4b4)
Te6edf3assertEqualsTb4b4b4(Tff7b72trueTb4b4b4, Te6edf3awaitItemTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3nodeDbResetPreserveFavoritesTb4b4b4)
Te6edf3cancelAndIgnoreRemainingEventsTb4b4b4(Tb4b4b4)
Tb4b4b4}
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`setOwner calls useCase`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3node Tff7b72= Te6edf3NodeTb4b4b4(Te6edf3num Tff7b72= T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!123Ta5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3nodeRepositoryTb4b4b4.Te6edf3setNodesTb4b4b4(Te6edf3listOfTb4b4b4(Te6edf3nodeTb4b4b4)Tb4b4b4)
Te6edf3viewModel Tff7b72= Te6edf3createViewModelTb4b4b4(Tb4b4b4)

Tff7b72val Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3long_name Tff7b72= Ta5d6ff"Ta5d6ffTest UserTa5d6ff"Tb4b4b4)
Te6edf3everySuspend Tb4b4b4{ Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3setOwnerTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3returns T79c0ff4T79c0ff2

Te6edf3viewModelTb4b4b4.Te6edf3setOwnerTb4b4b4(Te6edf3userTb4b4b4)

Te6edf3verifySuspend Tb4b4b4{ Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3setOwnerTb4b4b4(T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3userTb4b4b4) Tb4b4b4}
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`saveUserConfig sends setHamMode for licensed local node`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3node Tff7b72= Te6edf3NodeTb4b4b4(Te6edf3num Tff7b72= T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!123Ta5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3nodeRepositoryTb4b4b4.Te6edf3setNodesTb4b4b4(Te6edf3listOfTb4b4b4(Te6edf3nodeTb4b4b4)Tb4b4b4)
Te6edf3nodeRepositoryTb4b4b4.Te6edf3setMyNodeInfoTb4b4b4(Te6edf3myNodeInfoTb4b4b4(Te6edf3myNodeNum Tff7b72= T79c0ff1T79c0ff2T79c0ff3Tb4b4b4)Tb4b4b4)
Te6edf3viewModel Tff7b72= Te6edf3createViewModelTb4b4b4(Tb4b4b4)

Tff7b72val Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3long_name Tff7b72= Ta5d6ff"Ta5d6ffKK7ABCTa5d6ff"Tb4b4b4, Te6edf3short_name Tff7b72= Ta5d6ff"Ta5d6ffKK7ATa5d6ff"Tb4b4b4, Te6edf3is_licensed Tff7b72= Tff7b72trueTb4b4b4)
Te6edf3everySuspend Tb4b4b4{ Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3setHamModeTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3returns T79c0ff4T79c0ff2

Te6edf3viewModelTb4b4b4.Te6edf3saveUserConfigTb4b4b4(Te6edf3userTb4b4b4)

Te6edf3verifySuspend Tb4b4b4{ Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3setHamModeTb4b4b4(T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3HamParametersTb4b4b4(Te6edf3call_sign Tff7b72= Ta5d6ff"Ta5d6ffKK7ABCTa5d6ff"Tb4b4b4, Te6edf3short_name Tff7b72= Ta5d6ff"Ta5d6ffKK7ATa5d6ff"Tb4b4b4)Tb4b4b4) Tb4b4b4}
Te6edf3verifySuspendTb4b4b4(Te6edf3exactlyTb4b4b4(T79c0ff0Tb4b4b4)Tb4b4b4) Tb4b4b4{ Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3setOwnerTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`saveUserConfig sends setOwner for unlicensed user`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3node Tff7b72= Te6edf3NodeTb4b4b4(Te6edf3num Tff7b72= T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!123Ta5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3nodeRepositoryTb4b4b4.Te6edf3setNodesTb4b4b4(Te6edf3listOfTb4b4b4(Te6edf3nodeTb4b4b4)Tb4b4b4)
Te6edf3nodeRepositoryTb4b4b4.Te6edf3setMyNodeInfoTb4b4b4(Te6edf3myNodeInfoTb4b4b4(Te6edf3myNodeNum Tff7b72= T79c0ff1T79c0ff2T79c0ff3Tb4b4b4)Tb4b4b4)
Te6edf3viewModel Tff7b72= Te6edf3createViewModelTb4b4b4(Tb4b4b4)

Tff7b72val Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3long_name Tff7b72= Ta5d6ff"Ta5d6ffTest UserTa5d6ff"Tb4b4b4, Te6edf3short_name Tff7b72= Ta5d6ff"Ta5d6ffTUTa5d6ff"Tb4b4b4)
Te6edf3everySuspend Tb4b4b4{ Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3setOwnerTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3returns T79c0ff4T79c0ff2

Te6edf3viewModelTb4b4b4.Te6edf3saveUserConfigTb4b4b4(Te6edf3userTb4b4b4)

Te6edf3verifySuspend Tb4b4b4{ Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3setOwnerTb4b4b4(T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3userTb4b4b4) Tb4b4b4}
Te6edf3verifySuspendTb4b4b4(Te6edf3exactlyTb4b4b4(T79c0ff0Tb4b4b4)Tb4b4b4) Tb4b4b4{ Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3setHamModeTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`saveUserConfig never sends setHamMode to a remote node`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3localNode Tff7b72= Te6edf3NodeTb4b4b4(Te6edf3num Tff7b72= T79c0ff1T79c0ff0T79c0ff0Tb4b4b4, Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!100Ta5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72val Te6edf3remoteNode Tff7b72= Te6edf3NodeTb4b4b4(Te6edf3num Tff7b72= T79c0ff4T79c0ff5T79c0ff6Tb4b4b4, Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!456Ta5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3nodeRepositoryTb4b4b4.Te6edf3setNodesTb4b4b4(Te6edf3listOfTb4b4b4(Te6edf3localNodeTb4b4b4, Te6edf3remoteNodeTb4b4b4)Tb4b4b4)
Te6edf3nodeRepositoryTb4b4b4.Te6edf3setMyNodeInfoTb4b4b4(Te6edf3myNodeInfoTb4b4b4(Te6edf3myNodeNum Tff7b72= T79c0ff1T79c0ff0T79c0ff0Tb4b4b4)Tb4b4b4)
Te6edf3viewModel Tff7b72= Te6edf3createViewModelTb4b4b4(Te6edf3destNum Tff7b72= T79c0ff4T79c0ff5T79c0ff6Tb4b4b4)

Tff7b72val Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3long_name Tff7b72= Ta5d6ff"Ta5d6ffKK7ABCTa5d6ff"Tb4b4b4, Te6edf3short_name Tff7b72= Ta5d6ff"Ta5d6ffKK7ATa5d6ff"Tb4b4b4, Te6edf3is_licensed Tff7b72= Tff7b72trueTb4b4b4)
Te6edf3everySuspend Tb4b4b4{ Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3setOwnerTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3returns T79c0ff4T79c0ff2

Te6edf3viewModelTb4b4b4.Te6edf3saveUserConfigTb4b4b4(Te6edf3userTb4b4b4)

Te6edf3verifySuspend Tb4b4b4{ Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3setOwnerTb4b4b4(T79c0ff4T79c0ff5T79c0ff6Tb4b4b4, Te6edf3userTb4b4b4) Tb4b4b4}
Te6edf3verifySuspendTb4b4b4(Te6edf3exactlyTb4b4b4(T79c0ff0Tb4b4b4)Tb4b4b4) Tb4b4b4{ Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3setHamModeTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`saveUserConfig routes subsequent licensed saves to setOwner`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3node Tff7b72= Te6edf3NodeTb4b4b4(Te6edf3num Tff7b72= T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!123Ta5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3nodeRepositoryTb4b4b4.Te6edf3setNodesTb4b4b4(Te6edf3listOfTb4b4b4(Te6edf3nodeTb4b4b4)Tb4b4b4)
Te6edf3nodeRepositoryTb4b4b4.Te6edf3setMyNodeInfoTb4b4b4(Te6edf3myNodeInfoTb4b4b4(Te6edf3myNodeNum Tff7b72= T79c0ff1T79c0ff2T79c0ff3Tb4b4b4)Tb4b4b4)
Te6edf3viewModel Tff7b72= Te6edf3createViewModelTb4b4b4(Tb4b4b4)

Tff7b72val Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3long_name Tff7b72= Ta5d6ff"Ta5d6ffKK7ABCTa5d6ff"Tb4b4b4, Te6edf3short_name Tff7b72= Ta5d6ff"Ta5d6ffKK7ATa5d6ff"Tb4b4b4, Te6edf3is_licensed Tff7b72= Tff7b72trueTb4b4b4)
Te6edf3everySuspend Tb4b4b4{ Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3setHamModeTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3returns T79c0ff4T79c0ff2
Te6edf3everySuspend Tb4b4b4{ Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3setOwnerTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3returns T79c0ff4T79c0ff3

T8b949e// First save transitions OFF→ON and onboards via set_ham_mode.
Te6edf3viewModelTb4b4b4.Te6edf3saveUserConfigTb4b4b4(Te6edf3userTb4b4b4)
T8b949e// A later save while already licensed must use set_owner so other owner fields propagate.
Tff7b72val Te6edf3edited Tff7b72= Te6edf3userTb4b4b4.Te6edf3copyTb4b4b4(Te6edf3short_name Tff7b72= Ta5d6ff"Ta5d6ffKK7BTa5d6ff"Tb4b4b4)
Te6edf3viewModelTb4b4b4.Te6edf3saveUserConfigTb4b4b4(Te6edf3editedTb4b4b4)

Te6edf3verifySuspendTb4b4b4(Te6edf3exactlyTb4b4b4(T79c0ff1Tb4b4b4)Tb4b4b4) Tb4b4b4{ Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3setHamModeTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Te6edf3verifySuspend Tb4b4b4{ Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3setOwnerTb4b4b4(T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3editedTb4b4b4) Tb4b4b4}
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`saveUserConfig routes licensed save to setOwner when myNodeInfo is absent`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3node Tff7b72= Te6edf3NodeTb4b4b4(Te6edf3num Tff7b72= T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!123Ta5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3nodeRepositoryTb4b4b4.Te6edf3setNodesTb4b4b4(Te6edf3listOfTb4b4b4(Te6edf3nodeTb4b4b4)Tb4b4b4)
Te6edf3viewModel Tff7b72= Te6edf3createViewModelTb4b4b4(Tb4b4b4)

Tff7b72val Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3long_name Tff7b72= Ta5d6ff"Ta5d6ffKK7ABCTa5d6ff"Tb4b4b4, Te6edf3short_name Tff7b72= Ta5d6ff"Ta5d6ffKK7ATa5d6ff"Tb4b4b4, Te6edf3is_licensed Tff7b72= Tff7b72trueTb4b4b4)
Te6edf3everySuspend Tb4b4b4{ Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3setOwnerTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3returns T79c0ff4T79c0ff2

Te6edf3viewModelTb4b4b4.Te6edf3saveUserConfigTb4b4b4(Te6edf3userTb4b4b4)

Te6edf3verifySuspend Tb4b4b4{ Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3setOwnerTb4b4b4(T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3userTb4b4b4) Tb4b4b4}
Te6edf3verifySuspendTb4b4b4(Te6edf3exactlyTb4b4b4(T79c0ff0Tb4b4b4)Tb4b4b4) Tb4b4b4{ Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3setHamModeTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`setRingtone calls useCase`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3node Tff7b72= Te6edf3NodeTb4b4b4(Te6edf3num Tff7b72= T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!123Ta5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3nodeRepositoryTb4b4b4.Te6edf3setNodesTb4b4b4(Te6edf3listOfTb4b4b4(Te6edf3nodeTb4b4b4)Tb4b4b4)
Te6edf3viewModel Tff7b72= Te6edf3createViewModelTb4b4b4(Tb4b4b4)

Te6edf3everySuspend Tb4b4b4{ Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3setRingtoneTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3returns Tffa657Unit

Te6edf3viewModelTb4b4b4.Te6edf3setRingtoneTb4b4b4(Ta5d6ff"Ta5d6ffringtone.mp3Ta5d6ff"Tb4b4b4)

Te6edf3assertEqualsTb4b4b4(Ta5d6ff"Ta5d6ffringtone.mp3Ta5d6ff"Tb4b4b4, Te6edf3viewModelTb4b4b4.Te6edf3radioConfigStateTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3ringtoneTb4b4b4)
Te6edf3verifySuspend Tb4b4b4{ Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3setRingtoneTb4b4b4(T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Ta5d6ff"Ta5d6ffringtone.mp3Ta5d6ff"Tb4b4b4) Tb4b4b4}
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`setCannedMessages calls useCase`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3node Tff7b72= Te6edf3NodeTb4b4b4(Te6edf3num Tff7b72= T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!123Ta5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3nodeRepositoryTb4b4b4.Te6edf3setNodesTb4b4b4(Te6edf3listOfTb4b4b4(Te6edf3nodeTb4b4b4)Tb4b4b4)
Te6edf3viewModel Tff7b72= Te6edf3createViewModelTb4b4b4(Tb4b4b4)

Te6edf3everySuspend Tb4b4b4{ Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3setCannedMessagesTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3returns Tffa657Unit

Te6edf3viewModelTb4b4b4.Te6edf3setCannedMessagesTb4b4b4(Ta5d6ff"Ta5d6ffHello|WorldTa5d6ff"Tb4b4b4)

Te6edf3assertEqualsTb4b4b4(Ta5d6ff"Ta5d6ffHello|WorldTa5d6ff"Tb4b4b4, Te6edf3viewModelTb4b4b4.Te6edf3radioConfigStateTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3cannedMessageMessagesTb4b4b4)
Te6edf3verifySuspend Tb4b4b4{ Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3setCannedMessagesTb4b4b4(T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Ta5d6ff"Ta5d6ffHello|WorldTa5d6ff"Tb4b4b4) Tb4b4b4}
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`destNum from SavedStateHandle resolves destNode`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3node Tff7b72= Te6edf3NodeTb4b4b4(Te6edf3num Tff7b72= T79c0ff4T79c0ff5T79c0ff6Tb4b4b4, Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!456Ta5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3nodeRepositoryTb4b4b4.Te6edf3setNodesTb4b4b4(Te6edf3listOfTb4b4b4(Te6edf3nodeTb4b4b4)Tb4b4b4)
Te6edf3viewModel Tff7b72=
Te6edf3RadioConfigViewModelTb4b4b4(
Te6edf3destNum Tff7b72= T79c0ff4T79c0ff5T79c0ff6Tb4b4b4,
Te6edf3radioConfigRepository Tff7b72= Te6edf3radioConfigRepositoryTb4b4b4,
Te6edf3packetRepository Tff7b72= Te6edf3packetRepositoryTb4b4b4,
Te6edf3serviceRepository Tff7b72= Te6edf3serviceRepositoryTb4b4b4,
Te6edf3nodeRepository Tff7b72= Te6edf3nodeRepositoryTb4b4b4,
Te6edf3locationRepository Tff7b72= Te6edf3locationRepositoryTb4b4b4,
Te6edf3mapConsentPrefs Tff7b72= Te6edf3mapConsentPrefsTb4b4b4,
Te6edf3analyticsPrefs Tff7b72= Te6edf3analyticsPrefsTb4b4b4,
Te6edf3homoglyphEncodingPrefs Tff7b72= Te6edf3homoglyphEncodingPrefsTb4b4b4,
Te6edf3importProfileUseCase Tff7b72= Te6edf3importProfileUseCaseTb4b4b4,
Te6edf3exportProfileUseCase Tff7b72= Te6edf3exportProfileUseCaseTb4b4b4,
Te6edf3exportSecurityConfigUseCase Tff7b72= Te6edf3exportSecurityConfigUseCaseTb4b4b4,
Te6edf3installProfileUseCase Tff7b72= Te6edf3installProfileUseCaseTb4b4b4,
Te6edf3radioConfigUseCase Tff7b72= Te6edf3radioConfigUseCaseTb4b4b4,
Te6edf3adminActionsUseCase Tff7b72= Te6edf3adminActionsUseCaseTb4b4b4,
Te6edf3processRadioResponseUseCase Tff7b72= Te6edf3processRadioResponseUseCaseTb4b4b4,
Te6edf3locationService Tff7b72= Te6edf3locationServiceTb4b4b4,
Te6edf3fileService Tff7b72= Te6edf3fileServiceTb4b4b4,
Te6edf3mqttManager Tff7b72= Te6edf3mqttManagerTb4b4b4,
Te6edf3lockdownCoordinator Tff7b72= Te6edf3FakeLockdownCoordinatorTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff4T79c0ff5T79c0ff6Tb4b4b4, Te6edf3viewModelTb4b4b4.Te6edf3destNodeTb4b4b4.Te6edf3valueTff7b72?.Te6edf3numTb4b4b4)
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`setModuleConfig calls useCase`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3node Tff7b72= Te6edf3NodeTb4b4b4(Te6edf3num Tff7b72= T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!123Ta5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3nodeRepositoryTb4b4b4.Te6edf3setNodesTb4b4b4(Te6edf3listOfTb4b4b4(Te6edf3nodeTb4b4b4)Tb4b4b4)
Te6edf3viewModel Tff7b72= Te6edf3createViewModelTb4b4b4(Tb4b4b4)

Tff7b72val Te6edf3config Tff7b72=
Te6edf3orgTb4b4b4.Te6edf3meshtasticTb4b4b4.Te6edf3protoTb4b4b4.Te6edf3ModuleConfigTb4b4b4(Te6edf3mqtt Tff7b72= Te6edf3orgTb4b4b4.Te6edf3meshtasticTb4b4b4.Te6edf3protoTb4b4b4.Te6edf3ModuleConfigTb4b4b4.Te6edf3MQTTConfigTb4b4b4(Te6edf3enabled Tff7b72= Tff7b72trueTb4b4b4)Tb4b4b4)
Te6edf3everySuspend Tb4b4b4{ Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3setModuleConfigTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3returns T79c0ff4T79c0ff2

Te6edf3viewModelTb4b4b4.Te6edf3setModuleConfigTb4b4b4(Te6edf3configTb4b4b4)

Te6edf3verifySuspend Tb4b4b4{ Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3setModuleConfigTb4b4b4(T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3configTb4b4b4) Tb4b4b4}
Te6edf3assertEqualsTb4b4b4(Tff7b72trueTb4b4b4, Te6edf3viewModelTb4b4b4.Te6edf3radioConfigStateTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3moduleConfigTb4b4b4.Te6edf3mqttTff7b72?.Te6edf3enabledTb4b4b4)
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`setFixedPosition calls useCase`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3node Tff7b72= Te6edf3NodeTb4b4b4(Te6edf3num Tff7b72= T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!123Ta5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3nodeRepositoryTb4b4b4.Te6edf3setNodesTb4b4b4(Te6edf3listOfTb4b4b4(Te6edf3nodeTb4b4b4)Tb4b4b4)
Te6edf3viewModel Tff7b72= Te6edf3createViewModelTb4b4b4(Tb4b4b4)

Tff7b72val Te6edf3pos Tff7b72= Te6edf3orgTb4b4b4.Te6edf3meshtasticTb4b4b4.Te6edf3coreTb4b4b4.Te6edf3modelTb4b4b4.Te6edf3PositionTb4b4b4(Te6edf3latitude Tff7b72= T79c0ff1.0Tb4b4b4, Te6edf3longitude Tff7b72= T79c0ff2.0Tb4b4b4, Te6edf3altitude Tff7b72= T79c0ff0Tb4b4b4)
Te6edf3everySuspend Tb4b4b4{ Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3setFixedPositionTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3returns Tffa657Unit

Te6edf3viewModelTb4b4b4.Te6edf3setFixedPositionTb4b4b4(Te6edf3posTb4b4b4)

Te6edf3verifySuspend Tb4b4b4{ Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3setFixedPositionTb4b4b4(T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3posTb4b4b4) Tb4b4b4}
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`removeFixedPosition calls useCase`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3node Tff7b72= Te6edf3NodeTb4b4b4(Te6edf3num Tff7b72= T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!123Ta5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3nodeRepositoryTb4b4b4.Te6edf3setNodesTb4b4b4(Te6edf3listOfTb4b4b4(Te6edf3nodeTb4b4b4)Tb4b4b4)
Te6edf3viewModel Tff7b72= Te6edf3createViewModelTb4b4b4(Tb4b4b4)

Te6edf3everySuspend Tb4b4b4{ Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3removeFixedPositionTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3returns Tffa657Unit

Te6edf3viewModelTb4b4b4.Te6edf3removeFixedPositionTb4b4b4(Tb4b4b4)

Te6edf3verifySuspend Tb4b4b4{ Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3removeFixedPositionTb4b4b4(T79c0ff1T79c0ff2T79c0ff3Tb4b4b4) Tb4b4b4}
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`installProfile calls useCase`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3node Tff7b72= Te6edf3NodeTb4b4b4(Te6edf3num Tff7b72= T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!123Ta5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3nodeRepositoryTb4b4b4.Te6edf3setNodesTb4b4b4(Te6edf3listOfTb4b4b4(Te6edf3nodeTb4b4b4)Tb4b4b4)
Te6edf3viewModel Tff7b72= Te6edf3createViewModelTb4b4b4(Tb4b4b4)

Tff7b72val Te6edf3profile Tff7b72= Te6edf3DeviceProfileTb4b4b4(Tb4b4b4)
Te6edf3everySuspend Tb4b4b4{ Te6edf3installProfileUseCaseTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3returns Tffa657Unit

Te6edf3viewModelTb4b4b4.Te6edf3installProfileTb4b4b4(Te6edf3profileTb4b4b4)

Te6edf3verifySuspend Tb4b4b4{ Te6edf3installProfileUseCaseTb4b4b4(T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3profileTb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`processPacketResponse updates state on various results`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3node Tff7b72= Te6edf3NodeTb4b4b4(Te6edf3num Tff7b72= T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!123Ta5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3nodeRepositoryTb4b4b4.Te6edf3setNodesTb4b4b4(Te6edf3listOfTb4b4b4(Te6edf3nodeTb4b4b4)Tb4b4b4)
Tff7b72val Te6edf3packetFlow Tff7b72= Te6edf3MutableSharedFlowTff7b72<Te6edf3MeshPacketTff7b72>Tb4b4b4(Tb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3serviceRepositoryTb4b4b4.Te6edf3meshPacketFlow Tb4b4b4} Te6edf3returns Te6edf3packetFlow

Te6edf3viewModel Tff7b72= Te6edf3createViewModelTb4b4b4(Tb4b4b4)

T8b949e// ConfigResponse
Tff7b72val Te6edf3configResponse Tff7b72= Te6edf3ConfigTb4b4b4(Te6edf3lora Tff7b72= Te6edf3ConfigTb4b4b4.Te6edf3LoRaConfigTb4b4b4(Te6edf3hop_limit Tff7b72= T79c0ff5Tb4b4b4)Tb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3processRadioResponseUseCaseTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3returns
Te6edf3RadioResponseResultTb4b4b4.Te6edf3ConfigResponseTb4b4b4(Te6edf3configResponseTb4b4b4)
Te6edf3packetFlowTb4b4b4.Te6edf3emitTb4b4b4(Te6edf3MeshPacketTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff5Tb4b4b4, Te6edf3viewModelTb4b4b4.Te6edf3radioConfigStateTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3radioConfigTb4b4b4.Te6edf3loraTff7b72?.Te6edf3hop_limitTb4b4b4)

T8b949e// ModuleConfigResponse
Tff7b72val Te6edf3moduleResponse Tff7b72=
Te6edf3orgTb4b4b4.Te6edf3meshtasticTb4b4b4.Te6edf3protoTb4b4b4.Te6edf3ModuleConfigTb4b4b4(
Te6edf3telemetry Tff7b72= Te6edf3orgTb4b4b4.Te6edf3meshtasticTb4b4b4.Te6edf3protoTb4b4b4.Te6edf3ModuleConfigTb4b4b4.Te6edf3TelemetryConfigTb4b4b4(Te6edf3device_update_interval Tff7b72= T79c0ff3T79c0ff0T79c0ff0Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3processRadioResponseUseCaseTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3returns
Te6edf3RadioResponseResultTb4b4b4.Te6edf3ModuleConfigResponseTb4b4b4(Te6edf3moduleResponseTb4b4b4)
Te6edf3packetFlowTb4b4b4.Te6edf3emitTb4b4b4(Te6edf3MeshPacketTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(T79c0ff3T79c0ff0T79c0ff0Tb4b4b4, Te6edf3viewModelTb4b4b4.Te6edf3radioConfigStateTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3moduleConfigTb4b4b4.Te6edf3telemetryTff7b72?.Te6edf3device_update_intervalTb4b4b4)

T8b949e// Owner
Tff7b72val Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3long_name Tff7b72= Ta5d6ff"Ta5d6ffNew NameTa5d6ff"Tb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3processRadioResponseUseCaseTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3returns Te6edf3RadioResponseResultTb4b4b4.Te6edf3OwnerTb4b4b4(Te6edf3userTb4b4b4)
Te6edf3packetFlowTb4b4b4.Te6edf3emitTb4b4b4(Te6edf3MeshPacketTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(Ta5d6ff"Ta5d6ffNew NameTa5d6ff"Tb4b4b4, Te6edf3viewModelTb4b4b4.Te6edf3radioConfigStateTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3userConfigTb4b4b4.Te6edf3long_nameTb4b4b4)

T8b949e// Ringtone
Te6edf3every Tb4b4b4{ Te6edf3processRadioResponseUseCaseTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3returns Te6edf3RadioResponseResultTb4b4b4.Te6edf3RingtoneTb4b4b4(Ta5d6ff"Ta5d6ffbell.mp3Ta5d6ff"Tb4b4b4)
Te6edf3packetFlowTb4b4b4.Te6edf3emitTb4b4b4(Te6edf3MeshPacketTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(Ta5d6ff"Ta5d6ffbell.mp3Ta5d6ff"Tb4b4b4, Te6edf3viewModelTb4b4b4.Te6edf3radioConfigStateTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3ringtoneTb4b4b4)

T8b949e// Error
Te6edf3every Tb4b4b4{ Te6edf3processRadioResponseUseCaseTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3returns
Te6edf3RadioResponseResultTb4b4b4.Te6edf3ErrorTb4b4b4(Te6edf3orgTb4b4b4.Te6edf3meshtasticTb4b4b4.Te6edf3coreTb4b4b4.Te6edf3resourcesTb4b4b4.Te6edf3UiTextTb4b4b4.Te6edf3DynamicStringTb4b4b4(Ta5d6ff"Ta5d6ffFailTa5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3packetFlowTb4b4b4.Te6edf3emitTb4b4b4(Te6edf3MeshPacketTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3assertTrueTb4b4b4(Te6edf3viewModelTb4b4b4.Te6edf3radioConfigStateTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3responseState Tff7b72is Te6edf3ResponseStateTb4b4b4.Te6edf3ErrorTb4b4b4)
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`Admin actions call correct useCases`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3node Tff7b72= Te6edf3NodeTb4b4b4(Te6edf3num Tff7b72= T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!123Ta5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3nodeRepositoryTb4b4b4.Te6edf3setNodesTb4b4b4(Te6edf3listOfTb4b4b4(Te6edf3nodeTb4b4b4)Tb4b4b4)
Tff7b72val Te6edf3packetFlow Tff7b72= Te6edf3MutableSharedFlowTff7b72<Te6edf3MeshPacketTff7b72>Tb4b4b4(Tb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3serviceRepositoryTb4b4b4.Te6edf3meshPacketFlow Tb4b4b4} Te6edf3returns Te6edf3packetFlow

Te6edf3viewModel Tff7b72= Te6edf3createViewModelTb4b4b4(Tb4b4b4)

T8b949e// SHUTDOWN
Te6edf3everySuspend Tb4b4b4{ Te6edf3adminActionsUseCaseTb4b4b4.Te6edf3shutdownTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3returns T79c0ff4T79c0ff2
T8b949e// Set metadata to allow shutdown
Te6edf3every Tb4b4b4{ Te6edf3processRadioResponseUseCaseTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3returns
Te6edf3RadioResponseResultTb4b4b4.Te6edf3MetadataTb4b4b4(Te6edf3DeviceMetadataTb4b4b4(Te6edf3canShutdown Tff7b72= Tff7b72trueTb4b4b4)Tb4b4b4)
Te6edf3packetFlowTb4b4b4.Te6edf3emitTb4b4b4(Te6edf3MeshPacketTb4b4b4(Tb4b4b4)Tb4b4b4)

Te6edf3viewModelTb4b4b4.Te6edf3setResponseStateLoadingTb4b4b4(Te6edf3AdminRouteTb4b4b4.Te6edf3SHUTDOWNTb4b4b4)
T8b949e// AdminRoute fires sendAdminRequest after receiving ConfigResponse (session key),
T8b949e// not after a routing ACK (Success).
Te6edf3every Tb4b4b4{ Te6edf3processRadioResponseUseCaseTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3returns Te6edf3RadioResponseResultTb4b4b4.Te6edf3ConfigResponseTb4b4b4(Te6edf3ConfigTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3packetFlowTb4b4b4.Te6edf3emitTb4b4b4(Te6edf3MeshPacketTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3verifySuspend Tb4b4b4{ Te6edf3adminActionsUseCaseTb4b4b4.Te6edf3shutdownTb4b4b4(T79c0ff1T79c0ff2T79c0ff3Tb4b4b4) Tb4b4b4}

T8b949e// NODEDB_RESET
Te6edf3everySuspend Tb4b4b4{ Te6edf3adminActionsUseCaseTb4b4b4.Te6edf3nodedbResetTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3returns T79c0ff4T79c0ff2
Te6edf3viewModelTb4b4b4.Te6edf3setResponseStateLoadingTb4b4b4(Te6edf3AdminRouteTb4b4b4.Te6edf3NODEDB_RESETTb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3processRadioResponseUseCaseTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3returns Te6edf3RadioResponseResultTb4b4b4.Te6edf3ConfigResponseTb4b4b4(Te6edf3ConfigTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3packetFlowTb4b4b4.Te6edf3emitTb4b4b4(Te6edf3MeshPacketTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3verifySuspend Tb4b4b4{ Te6edf3adminActionsUseCaseTb4b4b4.Te6edf3nodedbResetTb4b4b4(T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`setResponseStateLoading for various routes calls correct useCases`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3node Tff7b72= Te6edf3NodeTb4b4b4(Te6edf3num Tff7b72= T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!123Ta5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3nodeRepositoryTb4b4b4.Te6edf3setNodesTb4b4b4(Te6edf3listOfTb4b4b4(Te6edf3nodeTb4b4b4)Tb4b4b4)
Te6edf3viewModel Tff7b72= Te6edf3createViewModelTb4b4b4(Tb4b4b4)

T8b949e// USER
Te6edf3everySuspend Tb4b4b4{ Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3getOwnerTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3returns T79c0ff4T79c0ff2
Te6edf3viewModelTb4b4b4.Te6edf3setResponseStateLoadingTb4b4b4(Te6edf3ConfigRouteTb4b4b4.Te6edf3USERTb4b4b4)
Te6edf3verifySuspend Tb4b4b4{ Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3getOwnerTb4b4b4(T79c0ff1T79c0ff2T79c0ff3Tb4b4b4) Tb4b4b4}

T8b949e// CHANNELS
Te6edf3everySuspend Tb4b4b4{ Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3getChannelTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3returns T79c0ff4T79c0ff2
Te6edf3everySuspend Tb4b4b4{ Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3getConfigTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3returns T79c0ff4T79c0ff2
Te6edf3viewModelTb4b4b4.Te6edf3setResponseStateLoadingTb4b4b4(Te6edf3ConfigRouteTb4b4b4.Te6edf3CHANNELSTb4b4b4)
Te6edf3verifySuspend Tb4b4b4{ Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3getChannelTb4b4b4(T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, T79c0ff0Tb4b4b4) Tb4b4b4}
Te6edf3verifySuspend Tb4b4b4{
Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3getConfigTb4b4b4(T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3orgTb4b4b4.Te6edf3meshtasticTb4b4b4.Te6edf3protoTb4b4b4.Te6edf3AdminMessageTb4b4b4.Te6edf3ConfigTypeTb4b4b4.Te6edf3LORA_CONFIGTb4b4b4.Te6edf3valueTb4b4b4)
Tb4b4b4}

T8b949e// LORA
Te6edf3viewModelTb4b4b4.Te6edf3setResponseStateLoadingTb4b4b4(Te6edf3ConfigRouteTb4b4b4.Te6edf3LORATb4b4b4)
Te6edf3verifySuspend Tb4b4b4{ Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3getConfigTb4b4b4(T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3ConfigRouteTb4b4b4.Te6edf3LORATb4b4b4.Te6edf3typeTb4b4b4) Tb4b4b4}
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`registerRequestId timeout clears request and sets error`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3node Tff7b72= Te6edf3NodeTb4b4b4(Te6edf3num Tff7b72= T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!123Ta5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3nodeRepositoryTb4b4b4.Te6edf3setNodesTb4b4b4(Te6edf3listOfTb4b4b4(Te6edf3nodeTb4b4b4)Tb4b4b4)
Te6edf3viewModel Tff7b72= Te6edf3createViewModelTb4b4b4(Tb4b4b4)

Te6edf3everySuspend Tb4b4b4{ Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3getOwnerTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3returns T79c0ff4T79c0ff2

Te6edf3viewModelTb4b4b4.Te6edf3setResponseStateLoadingTb4b4b4(Te6edf3ConfigRouteTb4b4b4.Te6edf3USERTb4b4b4)

T8b949e// state should be loading
Te6edf3assertTrueTb4b4b4(Te6edf3viewModelTb4b4b4.Te6edf3radioConfigStateTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3responseState Tff7b72is Te6edf3ResponseStateTb4b4b4.Te6edf3LoadingTb4b4b4)

T8b949e// advance time past 30 seconds
Te6edf3advanceTimeByTb4b4b4(T79c0ff3T79c0ff1Te6edf3_000Tb4b4b4)
Te6edf3runCurrentTb4b4b4(Tb4b4b4)

T8b949e// after timeout, the request ID should be removed, and if empty, sendError is called.
T8b949e// It's hard to assert sendError directly without a mock on a channel, but we can verify it doesn't stay loading
T8b949e// actually sendError updates the state? No, sendError sends an event.
T8b949e// But the requestIds gets cleared.
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`ensureLoadingForRemote sets loading state for remote nodes`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3localNode Tff7b72= Te6edf3NodeTb4b4b4(Te6edf3num Tff7b72= T79c0ff1T79c0ff0T79c0ff0Tb4b4b4, Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!100Ta5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72val Te6edf3remoteNode Tff7b72= Te6edf3NodeTb4b4b4(Te6edf3num Tff7b72= T79c0ff4T79c0ff5T79c0ff6Tb4b4b4, Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!456Ta5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3nodeRepositoryTb4b4b4.Te6edf3setNodesTb4b4b4(Te6edf3listOfTb4b4b4(Te6edf3localNodeTb4b4b4, Te6edf3remoteNodeTb4b4b4)Tb4b4b4)
Te6edf3nodeRepositoryTb4b4b4.Te6edf3setMyNodeInfoTb4b4b4(Te6edf3myNodeInfoTb4b4b4(Te6edf3myNodeNum Tff7b72= T79c0ff1T79c0ff0T79c0ff0Tb4b4b4)Tb4b4b4)

Tff7b72val Te6edf3remoteVm Tff7b72= Te6edf3createViewModelTb4b4b4(Te6edf3destNum Tff7b72= T79c0ff4T79c0ff5T79c0ff6Tb4b4b4)

T8b949e// Remote VM starts with Empty responseState
Te6edf3assertEqualsTb4b4b4(Te6edf3ResponseStateTb4b4b4.Te6edf3EmptyTb4b4b4, Te6edf3remoteVmTb4b4b4.Te6edf3radioConfigStateTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3responseStateTb4b4b4)
Te6edf3assertFalseTb4b4b4(Te6edf3remoteVmTb4b4b4.Te6edf3radioConfigStateTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3isLocalTb4b4b4)

T8b949e// ensureLoadingForRemote should transition to Loading
Te6edf3remoteVmTb4b4b4.Te6edf3ensureLoadingForRemoteTb4b4b4(Tb4b4b4)
Te6edf3assertTrueTb4b4b4(Te6edf3remoteVmTb4b4b4.Te6edf3radioConfigStateTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3responseState Tff7b72is Te6edf3ResponseStateTb4b4b4.Te6edf3LoadingTb4b4b4)
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`ensureLoadingForRemote is no-op for local nodes`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3localNode Tff7b72= Te6edf3NodeTb4b4b4(Te6edf3num Tff7b72= T79c0ff1T79c0ff0T79c0ff0Tb4b4b4, Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!100Ta5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3nodeRepositoryTb4b4b4.Te6edf3setNodesTb4b4b4(Te6edf3listOfTb4b4b4(Te6edf3localNodeTb4b4b4)Tb4b4b4)
Te6edf3nodeRepositoryTb4b4b4.Te6edf3setMyNodeInfoTb4b4b4(Te6edf3myNodeInfoTb4b4b4(Te6edf3myNodeNum Tff7b72= T79c0ff1T79c0ff0T79c0ff0Tb4b4b4)Tb4b4b4)

Tff7b72val Te6edf3localVm Tff7b72= Te6edf3createViewModelTb4b4b4(Te6edf3destNum Tff7b72= T79c0ff1T79c0ff0T79c0ff0Tb4b4b4)

T8b949e// Local VM should have isLocal = true
Te6edf3assertTrueTb4b4b4(Te6edf3localVmTb4b4b4.Te6edf3radioConfigStateTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3isLocalTb4b4b4)

T8b949e// ensureLoadingForRemote should NOT change responseState
Te6edf3localVmTb4b4b4.Te6edf3ensureLoadingForRemoteTb4b4b4(Tb4b4b4)
Te6edf3assertEqualsTb4b4b4(Te6edf3ResponseStateTb4b4b4.Te6edf3EmptyTb4b4b4, Te6edf3localVmTb4b4b4.Te6edf3radioConfigStateTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3responseStateTb4b4b4)
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`ensureLoadingForRemote is no-op when already loading`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3localNode Tff7b72= Te6edf3NodeTb4b4b4(Te6edf3num Tff7b72= T79c0ff1T79c0ff0T79c0ff0Tb4b4b4, Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!100Ta5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72val Te6edf3remoteNode Tff7b72= Te6edf3NodeTb4b4b4(Te6edf3num Tff7b72= T79c0ff4T79c0ff5T79c0ff6Tb4b4b4, Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!456Ta5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3nodeRepositoryTb4b4b4.Te6edf3setNodesTb4b4b4(Te6edf3listOfTb4b4b4(Te6edf3localNodeTb4b4b4, Te6edf3remoteNodeTb4b4b4)Tb4b4b4)
Te6edf3nodeRepositoryTb4b4b4.Te6edf3setMyNodeInfoTb4b4b4(Te6edf3myNodeInfoTb4b4b4(Te6edf3myNodeNum Tff7b72= T79c0ff1T79c0ff0T79c0ff0Tb4b4b4)Tb4b4b4)

Tff7b72val Te6edf3remoteVm Tff7b72= Te6edf3createViewModelTb4b4b4(Te6edf3destNum Tff7b72= T79c0ff4T79c0ff5T79c0ff6Tb4b4b4)

T8b949e// Set loading first
Te6edf3remoteVmTb4b4b4.Te6edf3ensureLoadingForRemoteTb4b4b4(Tb4b4b4)
Te6edf3assertTrueTb4b4b4(Te6edf3remoteVmTb4b4b4.Te6edf3radioConfigStateTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3responseState Tff7b72is Te6edf3ResponseStateTb4b4b4.Te6edf3LoadingTb4b4b4)

T8b949e// Calling again should still be Loading (no-op, not a new instance)
Te6edf3remoteVmTb4b4b4.Te6edf3ensureLoadingForRemoteTb4b4b4(Tb4b4b4)
Te6edf3assertTrueTb4b4b4(Te6edf3remoteVmTb4b4b4.Te6edf3radioConfigStateTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3responseState Tff7b72is Te6edf3ResponseStateTb4b4b4.Te6edf3LoadingTb4b4b4)
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`loraRegionPresetMapFlow populates state`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3node Tff7b72= Te6edf3NodeTb4b4b4(Te6edf3num Tff7b72= T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!123Ta5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3nodeRepositoryTb4b4b4.Te6edf3setNodesTb4b4b4(Te6edf3listOfTb4b4b4(Te6edf3nodeTb4b4b4)Tb4b4b4)
Tff7b72val Te6edf3mapFlow Tff7b72= Te6edf3MutableStateFlowTff7b72<Te6edf3LoRaRegionPresetMap?Tff7b72>Tb4b4b4(Tff7b72nullTb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3radioConfigRepositoryTb4b4b4.Te6edf3loraRegionPresetMapFlow Tb4b4b4} Te6edf3returns Te6edf3mapFlow
Te6edf3viewModel Tff7b72= Te6edf3createViewModelTb4b4b4(Tb4b4b4)
Te6edf3runCurrentTb4b4b4(Tb4b4b4)

Te6edf3assertEqualsTb4b4b4(Tff7b72nullTb4b4b4, Te6edf3viewModelTb4b4b4.Te6edf3radioConfigStateTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3loraRegionPresetMapTb4b4b4)

Tff7b72val Te6edf3map Tff7b72= Te6edf3LoRaRegionPresetMapTb4b4b4(Te6edf3groups Tff7b72= Te6edf3listOfTb4b4b4(Te6edf3LoRaPresetGroupTb4b4b4(Te6edf3licensed_only Tff7b72= Tff7b72trueTb4b4b4)Tb4b4b4)Tb4b4b4)
Te6edf3mapFlowTb4b4b4.Te6edf3value Tff7b72= Te6edf3map
Te6edf3runCurrentTb4b4b4(Tb4b4b4)

Te6edf3assertEqualsTb4b4b4(Te6edf3mapTb4b4b4, Te6edf3viewModelTb4b4b4.Te6edf3radioConfigStateTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3loraRegionPresetMapTb4b4b4)
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`localIsLicensed tracks the destination node's is_licensed flag`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
Tff7b72val Te6edf3node Tff7b72= Te6edf3NodeTb4b4b4(Te6edf3num Tff7b72= T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!123Ta5d6ff"Tb4b4b4, Te6edf3is_licensed Tff7b72= Tff7b72trueTb4b4b4)Tb4b4b4)
Te6edf3nodeRepositoryTb4b4b4.Te6edf3setNodesTb4b4b4(Te6edf3listOfTb4b4b4(Te6edf3nodeTb4b4b4)Tb4b4b4)
Te6edf3viewModel Tff7b72= Te6edf3createViewModelTb4b4b4(Tb4b4b4)
Te6edf3runCurrentTb4b4b4(Tb4b4b4)

Te6edf3assertTrueTb4b4b4(Te6edf3viewModelTb4b4b4.Te6edf3radioConfigStateTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3localIsLicensedTb4b4b4)
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`LoRa setConfig is not applied optimistically and issues no re-read`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTest Tb4b4b4{
T8b949e// A firmware region swap (e.g. EU sibling) is applied live; the form must reflect the device's actual
T8b949e// value, which is re-read on next LoRa-screen entry — NOT applied optimistically here, and the save ACK
T8b949e// must not trigger an in-place re-read (that would suppress the normal save-success UX).
Tff7b72val Te6edf3node Tff7b72= Te6edf3NodeTb4b4b4(Te6edf3num Tff7b72= T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3user Tff7b72= Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!123Ta5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3nodeRepositoryTb4b4b4.Te6edf3setNodesTb4b4b4(Te6edf3listOfTb4b4b4(Te6edf3nodeTb4b4b4)Tb4b4b4)
Te6edf3nodeRepositoryTb4b4b4.Te6edf3setMyNodeInfoTb4b4b4(Te6edf3myNodeInfoTb4b4b4(Te6edf3myNodeNum Tff7b72= T79c0ff1T79c0ff2T79c0ff3Tb4b4b4)Tb4b4b4)
Tff7b72val Te6edf3packetFlow Tff7b72= Te6edf3MutableSharedFlowTff7b72<Te6edf3MeshPacketTff7b72>Tb4b4b4(Tb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3serviceRepositoryTb4b4b4.Te6edf3meshPacketFlow Tb4b4b4} Te6edf3returns Te6edf3packetFlow
Te6edf3every Tb4b4b4{ Te6edf3radioConfigRepositoryTb4b4b4.Te6edf3localConfigFlow Tb4b4b4} Te6edf3returns
Te6edf3MutableStateFlowTb4b4b4(Te6edf3LocalConfigTb4b4b4(Te6edf3lora Tff7b72= Te6edf3ConfigTb4b4b4.Te6edf3LoRaConfigTb4b4b4(Te6edf3region Tff7b72= Te6edf3ConfigTb4b4b4.Te6edf3LoRaConfigTb4b4b4.Te6edf3RegionCodeTb4b4b4.Te6edf3EU_868Tb4b4b4)Tb4b4b4)Tb4b4b4)
Te6edf3viewModel Tff7b72= Te6edf3createViewModelTb4b4b4(Te6edf3destNum Tff7b72= T79c0ff1T79c0ff2T79c0ff3Tb4b4b4)
Te6edf3runCurrentTb4b4b4(Tb4b4b4)

Te6edf3everySuspend Tb4b4b4{ Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3setConfigTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3returns T79c0ff4T79c0ff2

Te6edf3viewModelTb4b4b4.Te6edf3setConfigTb4b4b4(Te6edf3ConfigTb4b4b4(Te6edf3lora Tff7b72= Te6edf3ConfigTb4b4b4.Te6edf3LoRaConfigTb4b4b4(Te6edf3region Tff7b72= Te6edf3ConfigTb4b4b4.Te6edf3LoRaConfigTb4b4b4.Te6edf3RegionCodeTb4b4b4.Te6edf3USTb4b4b4)Tb4b4b4)Tb4b4b4)
Te6edf3runCurrentTb4b4b4(Tb4b4b4)

T8b949e// The optimistic state still reflects the device's value, not the requested region.
Te6edf3assertEqualsTb4b4b4(Te6edf3ConfigTb4b4b4.Te6edf3LoRaConfigTb4b4b4.Te6edf3RegionCodeTb4b4b4.Te6edf3EU_868Tb4b4b4, Te6edf3viewModelTb4b4b4.Te6edf3radioConfigStateTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3radioConfigTb4b4b4.Te6edf3loraTff7b72?.Te6edf3regionTb4b4b4)

Te6edf3every Tb4b4b4{ Te6edf3processRadioResponseUseCaseTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, T79c0ff1T79c0ff2T79c0ff3Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3returns Te6edf3RadioResponseResultTb4b4b4.Te6edf3Success
Te6edf3packetFlowTb4b4b4.Te6edf3emitTb4b4b4(Te6edf3MeshPacketTb4b4b4(Te6edf3decoded Tff7b72= Te6edf3DataTb4b4b4(Te6edf3request_id Tff7b72= T79c0ff4T79c0ff2Tb4b4b4)Tb4b4b4)Tb4b4b4)
Te6edf3runCurrentTb4b4b4(Tb4b4b4)

Te6edf3verifySuspendTb4b4b4(Te6edf3exactlyTb4b4b4(T79c0ff0Tb4b4b4)Tb4b4b4) Tb4b4b4{ Te6edf3radioConfigUseCaseTb4b4b4.Te6edf3getConfigTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}
Tb4b4b4}

Tff7b72private Tff7b72fun Td2a8ffmyNodeInfoTb4b4b4(Te6edf3myNodeNumTb4b4b4: Tffa657IntTb4b4b4) Tff7b72= Te6edf3MyNodeInfoTb4b4b4(
Te6edf3myNodeNum Tff7b72= Te6edf3myNodeNumTb4b4b4,
Te6edf3hasGPS Tff7b72= Tff7b72falseTb4b4b4,
Te6edf3model Tff7b72= Tff7b72nullTb4b4b4,
Te6edf3firmwareVersion Tff7b72= Tff7b72nullTb4b4b4,
Te6edf3couldUpdate Tff7b72= Tff7b72falseTb4b4b4,
Te6edf3shouldUpdate Tff7b72= Tff7b72falseTb4b4b4,
Te6edf3currentPacketId Tff7b72= T79c0ff0Tb4b4b4,
Te6edf3messageTimeoutMsec Tff7b72= T79c0ff0Tb4b4b4,
Te6edf3minAppVersion Tff7b72= T79c0ff0Tb4b4b4,
Te6edf3maxChannels Tff7b72= T79c0ff8Tb4b4b4,
Te6edf3hasWifi Tff7b72= Tff7b72falseTb4b4b4,
Te6edf3channelUtilization Tff7b72= T79c0ff0fTb4b4b4,
Te6edf3airUtilTx Tff7b72= T79c0ff0fTb4b4b4,
Te6edf3deviceId Tff7b72= Tff7b72nullTb4b4b4,
Tb4b4b4)
Tb4b4b4}

Served by rngit 1.5.0 - Generated in 0.26s